using System;
using System.Collections.Generic;
using System.Linq;
//using System.Speech.Recognition;
using Microsoft.Speech.AudioFormat;
using Microsoft.Speech.Recognition;
using Coding4Fun.Kinect.WinForm;
using Microsoft.Kinect;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;
using System.IO;
using ParticleSample;

namespace SpaceKinect
{
    //Needed to put here to make it available to multiple classes
    enum CollisionType { None, Boundary, Target, UFO, Player }
    enum PowerUpType { LavaCannon, Health, Invuln }

    public class GameplayScreen : GameScreen
    {
        //FIELDS
        #region Fields

        float pauseAlpha;

        #endregion

        #region Structs + Enumerations

        //struct Bullet
        //{
        //    public Vector3 position;
        //    public Quaternion rotation;
        //}

        struct Star
        {
            public Vector3 position;
        }

        //enum CollisionType { None, Boundary, Target, UFO }

        struct PowerupHUD
        {
            public Texture2D enabled;
            public Texture2D disabled;
            public String Name;
        }

        #endregion

        #region Numeric Game Variables

        float tmp = 0;

        //Width of the tunnel
        int mapWidth = 10;
        //Height of the tunnel
        int mapHeight = 7;
        //Used to generate continual tunnels
        int nextTunnel = -100;

        //Game Speed
        float gameSpeed = 2.0f;

        //No of targets generated when AddTargets() is called
        int noOfTargets = 20;

        //Speed of bullets (represents the time interval between shots; a larger number = slower firing rate) 
        float firingspeed = 200;
        //Default Weapon Speed
        float DefaultFiringSpeed = 200;

        float UFOFireRate = 100;

        //Whether or not debugmode is on
        bool debugmode = false;

        //Old keyboard state. Used to detect key presses
        KeyboardState oldstate = Keyboard.GetState();

        //Spread of the stars
        int starSpread = 4;             ///Default: 4
        //No of stars in the map
        int numberOfStars = 1000;       ///Default: 1,000
        // How far away from the highway they are
        int distanceAddition = 10;      ///Default: 10        

        //Window width
        int windowWidth;
        //Window height
        int windowHeight;
        #endregion

        #region Other Game Declarations

        bool autofire = false;
        bool clapreset = false;
        int ammocount = 20;
        double lastAmmoReplenishTime = 0;
        int ammoPerSecond = 1;
        int MaxAmmo = 30;

        //Random number generators
        static Random rnd = new Random();
        Random random = new Random(5);

        float chance;

        //Graphics
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        GraphicsDevice device;
        //VertexBuffer (Used to store data on GPU; saves sending exactly the same data to the GPU each frame)
        VertexBuffer mapVertexBuffer;
        //Effects
        Effect effect;
        ContentManager content;

        //Player ship object
        Player player;

        //Models
        Model targetModel;
        Model powerUpModel;

        //Textures
        Texture2D sceneryTexture;
        Texture2D bulletTexture;
        Texture2D bulletTexture2;
        Texture2D starTexture;
        Texture2D barTexture;
        //HUD bar
        Texture2D bar_life;
        Texture2D bar_health_enabled;
        Texture2D bar_health_disabled;
        Texture2D bar_health_end;
        Texture2D bar_music_muted;
        Texture2D bar_music_unmuted;
        
        //Bounding Box of map
        BoundingBox mapBox;

        //Matrices
        Matrix viewMatrix;
        Matrix projectionMatrix;

        //Vectors
        Vector3 cameraPosition;
        Vector3 cameraUpDirection;
        Vector3 lightDirection = new Vector3(3, -2, 5);

        //Lists
        List<Target> targetList = new List<Target>();
        List<Star> starList = new List<Star>();
        List<Bullet> bulletList = new List<Bullet>();
        List<Bullet> bulletList2 = new List<Bullet>();
        List<PowerupHUD> powerUpHUDList = new List<PowerupHUD>();
        List<UFO> UFOList = new List<UFO>();
        List<PowerUp> powerUpList = new List<PowerUp>();

        //Powerups
        //bool player.LavaCannon = false;
        //bool player.Invuln = false;

        //Sound
        SoundEffect soundRegBullet;
        SoundEffect soundLavaCannon;
        SoundEffectInstance soundLavaCannonInstance;
        SoundEffect soundExplosion;
        SoundEffect soundShipExplosion;
        SoundEffect soundPowerUp;
        SoundEffect soundBoundaryCollision;
        SoundEffect soundPlayerHit;
        SoundEffect soundUFODestroyed;
        Song music;

        //Difficulty
        Difficulty diff;

        float volume;
        Vector3 bullDistVec;

        //Reader and writer for the score
        StreamWriter writer;
        StreamReader reader;
        const string path = @"Score.txt";

        bool lavaCannonDemonstrate = false;

        //Getters and setters
        public static Random Random
        {
            get { return rnd; }
        }

        public SpriteBatch SpriteBatch
        {
            get { return spriteBatch; }
        }
        #endregion

        #region HUD
        //Big bold segoe
        SpriteFont debugFont;
        //Size 14 segoe
        SpriteFont smallFont;

        SpriteFont menuFont;

        //sixe 2x segoe
        SpriteFont gameFont;
        //Aiming reticle
        Texture2D reticle;
        //Rectangles
        Texture2D hudRectangleBig = null;
        Texture2D hudRectangleSmall = null;

        #region PauseMenu
        //Pausescreen background
        Texture2D pauseScreen;
        //Sliderballs for volume sliders
        Texture2D musicSliderBall;
        Texture2D selectedSliderBall;

        bool Paused = false;
        bool gameOver;
        bool Exit;

        int offsetX = -(1366 - GlobalVars.windowWidth)/2;
        int offsetY = -(768 - GlobalVars.windowHeight)/2;
        //See what is selected in the pause menu
        bool invertY = false;
        bool musicVolumeSelected = false;
        bool effectsVolumeSelected = false;

        SliderBar musicVolumeSlider;
        SliderBar effectsVolumeSlider;
        #endregion


        #endregion

        #region Kinect

        //Enable this to use kinect, otherwise keyboard is used to control
        bool KINECT_ENABLE = OptionsMenuScreen.kinectOff;
        KinectSensor sensor;
        Texture2D kinectRGB;
        bool resetjoints;

        #region Speech
        KinectAudioSource audio;
        SpeechRecognitionEngine sr;

        Stream stream;
        #endregion

        #region Debug
        bool debug = false;
        bool debugcamera = false;

        #endregion

        #region Joints

        Vector3 Head;
        Vector3 LH;
        Vector3 RH;

        Vector3 LHHome;
        Vector3 RHHome;

        #endregion

        #region Constants

        float HandYAboveHome = 30f;
        float TiltDifference = 30f;

        #endregion

        #endregion

        #region Fire
        // Here's the really fun part of the sample, the particle systems! These are
        // drawable game components, so we can just add them to the components
        // collection. Read more about each particle system in their respective source
        // files.
        //ExplosionParticleSystem explosion;
        //ExplosionSmokeParticleSystem smoke;

        // a timer that will tell us when it's time to trigger another explosion.
        const float TimeBetweenExplosions = 2.0f;
        float timeTillExplosion = 0.0f;

        #endregion


        //CONSTRUCTOR
        public GameplayScreen(string difficulty)
        {
            //content.RootDirectory = "Content";

            TransitionOnTime = TimeSpan.FromSeconds(1.5);
            TransitionOffTime = TimeSpan.FromSeconds(0.5);

            diff = new Difficulty(difficulty);

            mapWidth = diff.mapWidth;
            mapHeight = diff.mapHeight;
            noOfTargets = diff.startingAsteroids;
            gameSpeed = (float)diff.gameSpeed;
            ammoPerSecond = diff.AmmoRespawnRate;
            MaxAmmo = diff.MaxAmmo;
            

            // create the particle systems and add them to the components list.
            // we should never see more than one explosion at once
            //explosion = new ExplosionParticleSystem(this, 1);
            //Components.Add(explosion);

            // but the smoke from the explosion lingers a while.
            //smoke = new ExplosionSmokeParticleSystem(this, 2);
            //Components.Add(smoke);

            // enable the tap gesture for changing particle effects
            //TouchPanel.EnabledGestures = GestureType.Tap;
            Initialize();
        }

        //METHODS
        #region Initialization Methods

        public void Initialize()
        {
            
            //graphics.IsFullScreen = false;
            //graphics.ApplyChanges();

            //Window.Title = "Space Kinect";
            //ScreenManager.Game.Window.Title = "Space Kinect";
            #region Kinect
            //Joint home positions will be reset when the user enters view of the camera
            resetjoints = true;
            DiscoverKinectSensor();
            Head = new Vector3(0, 0, 0);
            LH = new Vector3(0, 0, 0);
            RH = new Vector3(0, 0, 0);
            #endregion

           // InitializeSpeech();
            //base.Initialize();
        }

        public override void LoadContent()
        {
            spriteBatch = ScreenManager.SpriteBatch;

            device = ScreenManager.GraphicsDevice;
            if (content == null)
                content = new ContentManager(ScreenManager.Game.Services, "Content");

            windowWidth = GlobalVars.windowWidth;
            windowHeight = GlobalVars.windowHeight;

            debugFont = content.Load<SpriteFont>("debugfont");
            smallFont = content.Load<SpriteFont>("small");
            gameFont = content.Load<SpriteFont>("gamefont");
            menuFont = content.Load<SpriteFont>("menufont");

            effect = content.Load<Effect>("effects");
            sceneryTexture = content.Load<Texture2D>("highway2");
            bulletTexture = content.Load<Texture2D>("bullet");
            bulletTexture2 = content.Load<Texture2D>("bullet2");
            starTexture = content.Load<Texture2D>("star1");
            reticle = content.Load<Texture2D>("reticle2");
            //userbar
            barTexture = content.Load<Texture2D>("DisplayBar");
            bar_life = content.Load<Texture2D>("Life");
            bar_health_disabled = content.Load<Texture2D>("health_disabled");
            bar_health_enabled = content.Load<Texture2D>("health_enabled");
            bar_health_end = content.Load<Texture2D>("health_end");
            bar_music_muted = content.Load<Texture2D>("music_muted");
            bar_music_unmuted = content.Load<Texture2D>("music_unmuted");

            pauseScreen = content.Load<Texture2D>("PauseScreen");
            musicSliderBall = content.Load<Texture2D>("sliderball");
            selectedSliderBall = content.Load<Texture2D>("sliderballselected");

            targetModel = content.Load<Model>("Asteroid");

            soundRegBullet = content.Load<SoundEffect>("BulletSound2");
            soundLavaCannon = content.Load<SoundEffect>("BulletSound");
            soundLavaCannonInstance = soundLavaCannon.CreateInstance();
            soundShipExplosion = content.Load<SoundEffect>("Explosion2");
            soundExplosion = content.Load<SoundEffect>("Explosion3");
            soundPowerUp = content.Load<SoundEffect>("PowerUpSound");
            soundBoundaryCollision = content.Load<SoundEffect>("sidecollision");
            soundUFODestroyed = content.Load<SoundEffect>("ufodestroyed");
            soundPlayerHit = content.Load<SoundEffect>("playerhit");

            if (OptionsMenuScreen.audioON == true)
            {
                music = content.Load<Song>("sadtouchMp3");
                MediaPlayer.Play(music);
                MediaPlayer.IsRepeating = true;
                MediaPlayer.Volume = 0.5f;
            }

            musicVolumeSlider = new SliderBar(new Vector2(638 + offsetX, 330), new Vector2(971 + offsetX, 330), 5f);
            effectsVolumeSlider = new SliderBar(new Vector2(638 + offsetX, 400), new Vector2(971 + offsetX, 400), 5f);
            
            LoadHUDRectangles();
            nextTunnel = -100;
            SetUpBoundingBoxes();
            AddTargets();
            nextTunnel = 0;
            SetUpShip();
            SetUpVertices();
            SetUpBoundingBoxes();
            SetUpStars(nextTunnel);
            AddTargets();
            AddPowerupHUD();
        }

        public void LoadHUDRectangles()
        {
            hudRectangleBig = new Texture2D(device, windowWidth, 40);
            Color[] BigRectangleData = new Color[windowWidth * 40];
            for (int i = 0; i < BigRectangleData.Length; i++)
            {
                BigRectangleData[i] = Color.Blue;
            }
            hudRectangleBig.SetData(BigRectangleData);

            hudRectangleSmall = new Texture2D(device, windowWidth - 10, 35);
            Color[] SmallRectangleData = new Color[(windowWidth - 10) * 35];
            for (int i = 0; i < SmallRectangleData.Length; i++)
            {
                SmallRectangleData[i] = Color.Black;
            }
            hudRectangleSmall.SetData(SmallRectangleData);
        }

        public override void UnloadContent()
        {
        }

        private void AddTargets()
        {
            float radius = 0.5f;
            if (targetList.Count <= diff.maxAsteroids - 20)
            {
                for (int i = 0; i < noOfTargets; i++)
                {
                    int x = random.Next(100) + nextTunnel + 100;
                    int y = random.Next(mapHeight);
                    int z = -random.Next(mapWidth);
                    radius = random.Next(1, 5);
                    radius = 1 / radius;

                    Target newTarget = new Target(targetModel, new Vector3(x, y, z), radius);
                    CollisionType colType = newTarget.CheckTargetSetUpCollision(mapBox, targetList);

                    if (colType == CollisionType.None)
                        targetList.Add(newTarget);
                    else
                        i--;
                }
            }
            else if (targetList.Count <= diff.maxAsteroids) //makes the number of asteroids up to the max number
            {
                int num = diff.maxAsteroids - targetList.Count;
                for (int i = 0; i < num; i++)
                {
                    int x = random.Next(100) + nextTunnel + 100;
                    int y = random.Next(mapHeight);
                    int z = -random.Next(mapWidth);
                    radius = random.Next(1, 5);
                    radius = 1 / radius;

                    Target newTarget = new Target(targetModel, new Vector3(x, y, z), radius);
                    CollisionType colType = newTarget.CheckTargetSetUpCollision(mapBox, targetList);

                    if (colType == CollisionType.None)
                        targetList.Add(newTarget);
                    else
                        i--;
                }
                
            }
        }

        private void CheckGeneratePowerUp()
        {
            PowerUp newPowerUp;
            chance = (float)random.NextDouble();
            float radius = 0.25f;

            if (chance < 0.03)
            {
                powerUpModel = content.Load<Model>("SphereBlue");
                newPowerUp = new PowerUp(player.TmpPowerUpLocation, radius, PowerUpType.Invuln, powerUpModel, player.Rotation);
                powerUpList.Add(newPowerUp);
            }
            else if (chance < 0.1)
            {
                powerUpModel = content.Load<Model>("Health");
                newPowerUp = new PowerUp(player.TmpPowerUpLocation, radius, PowerUpType.Health, powerUpModel, player.Rotation);
                powerUpList.Add(newPowerUp);
            }
            else if (chance < 0.2)
            {
                powerUpModel = content.Load<Model>("SphereOrange");
                newPowerUp = new PowerUp(player.TmpPowerUpLocation, radius, PowerUpType.LavaCannon, powerUpModel, player.Rotation);
                powerUpList.Add(newPowerUp);
            }
        }

        private void AddPowerupHUD()
        {
            //Lava cannon
            PowerupHUD lavaCnn = new PowerupHUD();
            lavaCnn.enabled = content.Load<Texture2D>("lava_enabled");
            lavaCnn.disabled = content.Load<Texture2D>("lava_disabled");
            lavaCnn.Name = "Lava Cannon";
            powerUpHUDList.Add(lavaCnn);

            //Invincible
            PowerupHUD invincible = new PowerupHUD();
            invincible.enabled = content.Load<Texture2D>("invincible_enabled");
            invincible.disabled = content.Load<Texture2D>("invincible_disabled");
            invincible.Name = "Invincibility";
            powerUpHUDList.Add(invincible);

            //Invert Y
            PowerupHUD inverty = new PowerupHUD();
            inverty.enabled = content.Load<Texture2D>("inverty_down");
            inverty.disabled = content.Load<Texture2D>("inverty_up");
            inverty.Name = "InvertY";
            powerUpHUDList.Add(inverty);
        }

        private void AddUFO()
        {
            Vector3 UFOPos = new Vector3(player.Position.X + 100, 2, -(float)mapWidth / 2);
            Quaternion UFORot = Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), MathHelper.PiOver2);
            Model UFOModel = content.Load<Model>("UFO");

            UFOList.Add(new UFO(UFOModel, UFOPos, UFORot));
        }

        private void SetUpShip()
        {
            //Position and rotation of starting position
            Vector3 shipPos = new Vector3(0, 2, -(float)mapWidth / 2);
            Quaternion shipRot = Quaternion.CreateFromAxisAngle(new Vector3(0, -1, 0), MathHelper.PiOver2);
            Model shipModel = content.Load<Model>("RocketPlain");

            player = new Player(shipModel, shipPos, shipRot);
        }

        private void SetUpVertices()
        {
            //Used to create the textures
            List<VertexPositionNormalTexture> allthethings = new List<VertexPositionNormalTexture>();
            for (int x = nextTunnel; x < nextTunnel + 200; x += 5)
            {
                //Highway
                allthethings.Add(new VertexPositionNormalTexture(new Vector3(x, 0, 0), new Vector3(0, 0, 0), new Vector2(0, 1)));
                allthethings.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -mapWidth), new Vector3(0, 0, 0), new Vector2(0, 0)));
                allthethings.Add(new VertexPositionNormalTexture(new Vector3(x + 5, 0, 0), new Vector3(0, 0, 0), new Vector2(1, 1)));

                allthethings.Add(new VertexPositionNormalTexture(new Vector3(x, 0, -mapWidth), new Vector3(0, 0, 0), new Vector2(0, 0)));
                allthethings.Add(new VertexPositionNormalTexture(new Vector3(x + 5, 0, -mapWidth), new Vector3(0, 0, 0), new Vector2(1, 0)));
                allthethings.Add(new VertexPositionNormalTexture(new Vector3(x + 5, 0, 0), new Vector3(0, 0, 0), new Vector2(1, 1)));

            }
            mapVertexBuffer = new VertexBuffer(device, VertexPositionNormalTexture.VertexDeclaration, allthethings.Count, BufferUsage.WriteOnly);
            mapVertexBuffer.SetData<VertexPositionNormalTexture>(allthethings.ToArray());
        }

        private void SetUpStars(int length)
        {
            //Adds stars
            for (int i = 0; i < numberOfStars; i++)
            {
                //Initialise + positions of stars
                Star temp = new Star();
                int x = rnd.Next(length + 200);
                int y = rnd.Next(starSpread * mapHeight) - ((starSpread / 4) * mapHeight);
                int z = -rnd.Next(starSpread * mapWidth) + ((starSpread / 2) * (mapWidth - 2));

                //If it is within the bounds of the map, make it... not
                int tempswitch1 = rnd.Next(2); // z or y to move
                int tempswitch2 = rnd.Next(2); //one side or another
                
                if ((y >= 0 && y <= mapHeight) && (z <= 0 && z >= -mapWidth))
                {
                    //Change y or z?
                    if (tempswitch1 == 0) //Change y
                    {
                        //Make it higher or lower by 1 mapwidth?
                        if (tempswitch2 == 0) //Higher
                        {
                            y += mapHeight;
                        }
                        else if (tempswitch2 == 1)  //Lower
                        {
                            y -= mapHeight;
                        }

                    }
                    else if (tempswitch1 == 1)  //Change Z
                    {
                        //Make it left or right by 1 mapwidth?
                        if (tempswitch2 == 0)  //Left
                        {
                            z -= mapWidth;
                        }
                        else if (tempswitch2 == 1)  //Lower
                        {
                            z += mapWidth;
                        }

                    }
                }

                //handles stars on the ground
                if (y == 0)
                {
                    y -= 2;
                }
                temp.position = new Vector3(x, y, z);
                starList.Add(temp);
            }


            //Removes old stars
            for (int i = 0; i < starList.Count; i++)
            {
                if (starList[i].position.X < player.Position.X - 200)
                {
                    starList.RemoveAt(i);
                }
            }

        }

        private void SetUpBoundingBoxes()
        {
            Vector3[] boundaryPoints = new Vector3[2];

            boundaryPoints[0] = new Vector3(nextTunnel - 100, 0, 0);
            boundaryPoints[1] = new Vector3(nextTunnel + 300, mapHeight, -mapWidth);
            mapBox = BoundingBox.CreateFromPoints(boundaryPoints);

        }

        private void OnDeath(GameTime gameTime)
        {
            soundShipExplosion.Play(0.5f * effectsVolumeSlider.getValue() / 10, 0, 0);
            player.Death(gameTime, mapWidth);      
            if (player.Lives == 0)
            {
                gameOver = true;
                Paused = true;
                RecordScore(player.TotalScore);
            }
        }

        #endregion

        #region Update Methods
        /// <summary>
        /// Updates the state of the game. This method checks the GameScreen.IsActive
        /// property, so the game will stop updating when the pause menu is active,
        /// or if you tab away to a different application.
        /// </summary>
        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)                                            
        {

            base.Update(gameTime, otherScreenHasFocus, false);

            // Gradually fade in or out depending on whether we are covered by the pause screen.
            //if (coveredByOtherScreen)
            //    pauseAlpha = Math.Min(pauseAlpha + 1f / 32, 1);
            //else
            //    pauseAlpha = Math.Max(pauseAlpha - 1f / 32, 0);

            if (IsActive)
            {
                #region KinectOutOfBounds
                //If player is not in kinect camera range
                if (CheckOutOfBounds())
                {
                    if (resetjoints == false)
                    {
                        resetjoints = true;
                        base.Draw(gameTime);
                    }
                    return;
                }
                if (Paused == true)
                    return;

                //If player has moved back in range
                if (resetjoints == true)
                {
                    RHHome = RH;
                    LHHome = LH;
                    resetjoints = false;
                }
                #endregion

                //Move the ship forward
                float moveSpeed = gameTime.ElapsedGameTime.Milliseconds / 500.0f * gameSpeed;
                float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;

                player.MoveForward(moveSpeed);
                UpdateAmmo(gameTime);
                UFOFireBullets(gameTime);

                //Update the bullets
                UpdateBullets(moveSpeed);

                //Update targets
                UpdateTargets(gameTime, moveSpeed);

                //Update UFOs
                UpdateUFOs(moveSpeed, gameTime);

                // if we should be demoing the explosions effect, check to see if it's
                // time for a new explosion.
                UpdateExplosions(dt);

                ProcessKeyboard(gameTime);
                UpdateCamera();

                //Check collisions of ship
                //BoundingSphere shipSphere = new BoundingSphere(shipPosition, 0.04f);
                player.UpdateBoundSphere();
                CheckShipCollision(player.Bound, gameTime);

                //Check health of player
                if (player.Health <= 0)
                    OnDeath(gameTime);      

                //Updates relevant powerups
                CheckPowerups(gameTime);

                //Checks when to create the next tunnel
                if ((int)player.Position.X > nextTunnel)
                    GenerateTunnel();

                //Update score
                player.TotalScore = (int)(player.Position.X / 2) + player.TargetScore;

                tmp = (float)rnd.NextDouble() + .3f;
            }
        }


        /// <summary>
        /// Lets the game respond to player input. Unlike the Update method,
        /// this will only be called when the gameplay screen is active.
        /// </summary>
        //public override void HandleInput(InputState input, GameTime gameTime)
        //{
        //    if (input == null)
        //        throw new ArgumentNullException("input");

        //    // Look up inputs for the active player profile.
        //    int playerIndex = (int)ControllingPlayer.Value;

        //    KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex];
        //    GamePadState gamePadState = input.CurrentGamePadStates[playerIndex];

        //    // The game pauses either if the user presses the pause button, or if
        //    // they unplug the active gamepad. This requires us to keep track of
        //    // whether a gamepad was ever plugged in, because we don't want to pause
        //    // on PC if they are playing with a keyboard and have no gamepad at all!
        //    bool gamePadDisconnected = !gamePadState.IsConnected &&
        //                               input.GamePadWasConnected[playerIndex];

        //    if (input.IsPauseGame(ControllingPlayer) || gamePadDisconnected)
        //    {
        //        Paused = true;
        //        DrawPauseMenu(gameTime);
        //    }
        //}

        // this function is called when we want to demo the explosion effect. it
        // updates the timeTillExplosion timer, and starts another explosion effect
        // when the timer reaches zero.
        private void UpdateExplosions(float dt)
        {
            timeTillExplosion -= dt;
            if (timeTillExplosion < 0)
            {
                Vector2 where = Vector2.Zero;
                // create the explosion at some random point on the screen.
                //where.X = RandomBetween(0, graphics.GraphicsDevice.Viewport.Width);
                where.X = player.Position.X;
                where.Y = player.Position.Y;
                //where.Y = RandomBetween(0, graphics.GraphicsDevice.Viewport.Height);

                // the overall explosion effect is actually comprised of two particle
                // systems: the fiery bit, and the smoke behind it. add particles to
                // both of those systems.
                //explosion.AddParticles(where);
                //smoke.AddParticles(where);

                // reset the timer.
                timeTillExplosion = TimeBetweenExplosions;
            }
        }

        private void UpdateCamera()
        {
            Vector3 campos = new Vector3(0, 0.1f, 0.6f);
            campos = Vector3.Transform(campos, Matrix.CreateFromQuaternion(player.Rotation));
            campos += player.Position;

            Vector3 camup = new Vector3(0, 1, 0);
            camup = Vector3.Transform(camup, Matrix.CreateFromQuaternion(player.Rotation));

            viewMatrix = Matrix.CreateLookAt(campos, player.Position, camup);
            projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, device.Viewport.AspectRatio, 0.2f, 100.0f);

            cameraPosition = campos;
            cameraUpDirection = camup;

        }

        private void UpdateBullets(float moveSpeed)
        {
            for (int i = 0; i < bulletList.Count; i++)
            {
                //Move bullet forward
                bulletList[i].Update(moveSpeed);
                
                //Check for a collision
                CollisionType colType = bulletList[i].CheckCollision(UFOList, targetList, mapBox, targetModel, player, diff);

                //Remove if there is one or if it goes 75 units ahead of the player
                if (colType != CollisionType.None || bulletList[i].Position.X - player.Position.X > 75)
                {
                    bulletList.RemoveAt(i);
                    i--;
                }

                if (colType == CollisionType.Target)
                {
                    player.TargetScore += 10;

                    if (player.LavaCannon == false)
                        player.DestroyedTargets++;

                    if (player.Explos == true)
                    {
                        PlayExplosion(player.ExplosVec.X);
                        player.Explos = false;
                    }

                     CheckGeneratePowerUp();
                }
            }

            for (int i = 0; i < bulletList2.Count; i++)
            {
                bulletList2[i].UpdateUFOBullet(moveSpeed, player, diff.UFOFireRate);

                CollisionType colType = bulletList2[i].CheckHit(player, targetList);

                if (colType == CollisionType.Player)
                {
                    if (player.Invuln == false)
                    {
                        player.Health -= 20;
                        soundPlayerHit.Play(effectsVolumeSlider.getValue() / 10, 0f, 0f);
                    }
                }
                 

                if (bulletList2[i].Position.X < player.Position.X || colType == CollisionType.Target)
                {
                    bulletList2.RemoveAt(i);
                    i--;
                }
            }

        }

        private void UpdateTargets(GameTime gameTime, float moveSpeed)
        {
            for (int i = 0; i < targetList.Count; i++)
            {
                //Update target method that doesn't really work (will fix if have time)
                //targetList[i].Update(player, gameTime, mapHeight, mapWidth, moveSpeed);

                //remove target if ship passes it
                if (targetList[i].Position.X - player.Position.X < 0)
                {
                    targetList.RemoveAt(i);
                    i--;
                }


            }
        }

        private void UpdateUFOs(float moveSpeed, GameTime gameTime)
        {
            for (int i = 0; i < UFOList.Count; i++)
            {
                UFOList[i].Update(moveSpeed, gameTime, mapHeight, mapWidth, player.Position.X);

                if (UFOList[i].Health <= 0)
                {
                    bullDistVec = (UFOList[i].Position - player.Position);
                    volume = (100 - bullDistVec.X) / 100f;
                    soundUFODestroyed.Play(volume * effectsVolumeSlider.getValue() / 10, 0f, 0f);

                    UFOList.RemoveAt(i);
                    i--;
                    player.TargetScore += 100;
                }
            }
        }

        private void MoveForward(ref Vector3 position, Quaternion rotationQuat, float speed)
        {
            Vector3 addVector = Vector3.Transform(new Vector3(0, 0, -1), rotationQuat);
            position += addVector * speed;
        }

        private void GenerateTunnel()
        {
            SetUpVertices();
            SetUpBoundingBoxes();
            nextTunnel += 100;
            AddTargets();
            SetUpStars(nextTunnel);

            if (diff.cyclesTillUFO < 1)
            {
                if (UFOList.Count < diff.maxUFOs)
                {
                    AddUFO();
                }
            }
            else
                diff.cyclesTillUFO--;

            //Gameplay elements that increase
            if (gameSpeed + diff.rateOfSpeedIncrease <= diff.maxGameSpeed)
            {
                gameSpeed += diff.rateOfSpeedIncrease;
            }
            else
            {
                gameSpeed = diff.maxGameSpeed;
            }
            noOfTargets++;
        }

        private void ProcessKeyboard(GameTime gameTime)
        {
            float leftRightRot = 0;
            float upDownRot = 0;
            //Speeds for turning/going up and down
            //Up/Down speed is considerably slower for ease of controlling with kinect
            float turningSpeed = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;
            float updownSpeed = (float)gameTime.ElapsedGameTime.TotalMilliseconds /700.0f;
            if (KINECT_ENABLE == true)
                updownSpeed /= 4;

            turningSpeed *= 1f;

            KeyboardState keys = Keyboard.GetState();

            //Handles whether or not we are in debugmode
            if (keys.IsKeyDown(Keys.OemTilde))
            {
                if (!oldstate.IsKeyDown(Keys.OemTilde))
                {
                    if (debugmode == false)
                        debugmode = true;
                    else
                        debugmode = false;
                }
            }

            //Mute audio
            if (keys.IsKeyDown(Keys.M))
            {
                if (!oldstate.IsKeyDown(Keys.M))
                {
                    if (MediaPlayer.IsMuted == false)
                    {
                        MediaPlayer.IsMuted = true;
                        OptionsMenuScreen.audioON = true;
                    }
                    else
                    {
                        MediaPlayer.IsMuted = false;
                        OptionsMenuScreen.audioON = false;
                    }
                }
            }

            //Recording score and Exit
            if (keys.IsKeyDown(Keys.Escape))
            {
                if (!oldstate.IsKeyDown(Keys.Escape))
                {
                    if (Paused == true)
                        Paused = false;
                    else
                        Paused = true;
                }
                //RecordScore(targetScore);
            }

            if (keys.IsKeyDown(Keys.L))
            {
                if (!oldstate.IsKeyDown(Keys.L))
                {
                    if (lavaCannonDemonstrate == true)
                        lavaCannonDemonstrate = false;
                    else
                        lavaCannonDemonstrate = true;
                }
                //RecordScore(targetScore);
            }

            oldstate = keys;


            if (keys.IsKeyDown(Keys.X))
            {
                gameOver = true;
                Paused = true;
            }
            //If user is controlling game with KINECT camera
            if (KINECT_ENABLE == true && Paused== false)
            {
                if (invertY == false)
                {

                    //Up
                    if ((RH.Y + LH.Y) / 2 + HandYAboveHome < RHHome.Y)
                    {
                        upDownRot += updownSpeed;
                    }
                    //Down
                    else if ((RH.Y + LH.Y) / 2 - HandYAboveHome > RHHome.Y)
                    {
                        upDownRot -= updownSpeed;
                    }
                }
                else
                {
                    //Up
                    if ((RH.Y + LH.Y) / 2 + HandYAboveHome < RHHome.Y)
                    {
                        upDownRot -= updownSpeed;
                    }
                    //Down
                    else if ((RH.Y + LH.Y) / 2 - HandYAboveHome > RHHome.Y)
                    {
                        upDownRot += updownSpeed;
                    }
                }
                //Turn Left
                if (LH.Y - RH.Y > TiltDifference)
                {
                    leftRightRot -= turningSpeed;
                }
                //Turn right
                else if (RH.Y - LH.Y > TiltDifference)
                {
                    leftRightRot += turningSpeed;
                }


                //Checks to see if hands have been clapped
                if (RH.X - LH.X < 5 && (RH.Y - LH.Y < 5 || LH.Y - RH.Y < 5) && clapreset == false)
                {
                    autofire = !autofire;
                    clapreset = true;
                }
                else if (RH.X - LH.X > 10)
                {
                    clapreset = false;
                }


                //fire bullets
                if (autofire == true && ammocount >0)
                {
                    PlayerFireBullets(gameTime);
                }

            }
            //If keyboard is being used
            else
            {
                if (keys.IsKeyDown(Keys.Down))
                    upDownRot -= turningSpeed;
                if (keys.IsKeyDown(Keys.Up))
                    upDownRot += turningSpeed;
                if (keys.IsKeyDown(Keys.Right))
                    leftRightRot += turningSpeed;
                if (keys.IsKeyDown(Keys.Left))
                    leftRightRot -= turningSpeed;
                if (keys.IsKeyDown(Keys.Space))
                {
                    PlayerFireBullets(gameTime);
                    autofire = true;
                    if (ammocount == 0)
                        autofire = false;

                }
                else
                {
                    autofire = false;
                }
            }

            Quaternion additionalRot = Quaternion.CreateFromAxisAngle(new Vector3(0, 0, -1), leftRightRot) * Quaternion.CreateFromAxisAngle(new Vector3(1, 0, 0), upDownRot);
            player.Rotation *= additionalRot;

            //strafing
            if (keys.IsKeyDown(Keys.W))
                player.Position -= new Vector3(0, -.015f, 0);
            if (keys.IsKeyDown(Keys.S))
                player.Position -= new Vector3(0, .015f, 0);
            if (keys.IsKeyDown(Keys.D))
                player.Position -= new Vector3(0, 0, -.015f);
            if (keys.IsKeyDown(Keys.A))
                player.Position -= new Vector3(0, 0, .015f);

            //Increase/decrease game speed
            if (keys.IsKeyDown(Keys.D1))
                gameSpeed *= 1.01f;
            if (keys.IsKeyDown(Keys.D2))
                gameSpeed /= 1.01f;

            
        }

        private void CheckforEscape()
        {
            KeyboardState keys = Keyboard.GetState();

            if (keys.IsKeyDown(Keys.Escape))
                Exit = true;
            else
                Exit = false;
        }

        private void CheckforQuit()
        {
            KeyboardState keys = Keyboard.GetState();

            if (keys.IsKeyDown(Keys.Q))
                Exit = true;
            else
                Exit = false;
        }

        private void ReturnToMainMenu()
        {
            MediaPlayer.Stop();
            ScreenManager.AddScreen(new BackgroundScreen(), null);
            ScreenManager.AddScreen(new MainMenuScreen(), null);
            ScreenManager.RemoveScreen(this);
        }

        private void PlayerFireBullets(GameTime gameTime)
        {
            double currentTime = gameTime.TotalGameTime.TotalMilliseconds;

            if (currentTime - player.LastBulletTime > firingspeed)
            {
                if (player.LavaCannon != true)
                {
                    ammocount--;
                    if (ammocount == 0)
                    {
                        autofire = false;
                    }
                }

                Bullet newBullet = new Bullet(bulletTexture, player.Position + new Vector3(0.1f, 0, 0), player.Rotation);
                bulletList.Add(newBullet);

                BulletSounds();

                player.LastBulletTime = currentTime;
            }
        }

        private void UFOFireBullets(GameTime gameTime)
        {
            double currentTime = gameTime.TotalGameTime.TotalMilliseconds;

            for (int i = 0; i < UFOList.Count; i++)
            {
                if (currentTime - UFOList[i].LastBulletTime > diff.UFOFireRate)
                {
                    if (UFOList[i].FiringValue > 0)
                    {
                        Bullet newBullet = new Bullet(bulletTexture2, UFOList[i].Position, UFOList[i].Rotation);
                        newBullet.DirectVector = (player.Position + new Vector3(30, 0, 0)) - UFOList[i].Position;
                        bulletList2.Add(newBullet);
                        UFOList[i].FiringValue += diff.UFOFireRate;

                        if (UFOList[i].FiringValue > diff.UFOFireToggleOnTime)
                        {
                            UFOList[i].FiringValue = -diff.UFOFireToggleOffTime;
                        }
                    }
                    else
                    {
                        UFOList[i].FiringValue += diff.UFOFireRate;
                    }

                    UFOList[i].LastBulletTime = currentTime;
                }
            }
        }

        private void BulletSounds()
        {
            if (player.LavaCannon == true)
            {
                if (soundLavaCannonInstance.State == SoundState.Stopped)
                    soundLavaCannonInstance.Play();
            }
            else
                soundRegBullet.Play(effectsVolumeSlider.getValue() / 10, 0f, 0f);
        }

        private void CheckPowerups(GameTime gameTime)
        {
            //If 5 targets have been destroyed
            if (lavaCannonDemonstrate == true)
            {
                if (player.DestroyedTargets >= 5)
                {
                    player.LavaCannon = true;
                    soundPowerUp.Play();
                    firingspeed = 1;
                    player.DestroyedTargets = 0;
                    player.LavaCannonStartTime = gameTime.TotalGameTime.TotalMilliseconds;
                }
            }

            //If powerup has expired
            if (player.LavaCannon == true)
            {
                if (gameTime.TotalGameTime.TotalMilliseconds - player.LavaCannonStartTime > 10000)
                {
                    player.LavaCannon = false;
                    firingspeed = DefaultFiringSpeed;
                }
            }
            if (player.Invuln == true)
            {
                if (gameTime.TotalGameTime.TotalMilliseconds - player.InvulnStartTime > 5000)
                    player.Invuln = false;
            }

            for (int i = 0; i < powerUpList.Count; i++)
                if (powerUpList[i].Position.X < player.Position.X)
                {
                    powerUpList.RemoveAt(i);
                    i--;
                }
        }

        private void UpdateAmmo(GameTime gameTime)
        {
            //Replenish 1 ammo every 1sec
            if (gameTime.TotalGameTime.TotalMilliseconds - lastAmmoReplenishTime > 1000/ammoPerSecond)
            {
                if(ammocount < MaxAmmo && autofire == false)
                ammocount++;
                lastAmmoReplenishTime = gameTime.TotalGameTime.TotalMilliseconds;
            }
        }
        private CollisionType CheckShipCollision(BoundingSphere sphere, GameTime gameTime)
        {
            //determines what the ship collided with

            //if sides of tunnel:
            if (mapBox.Contains(sphere) != ContainmentType.Contains)
            {
                //set the rotation flat, and facing forwards
                player.Rotation = Quaternion.CreateFromAxisAngle(new Vector3(0, -1, 0), MathHelper.PiOver2);

                //floor
                if (player.Position.Y < 1)
                    player.Position += new Vector3(0, 0.5f, 0);
                //roof
                if (player.Position.Y > mapHeight - 1)
                    player.Position += new Vector3(0, -0.5f, 0);
                //left wall
                if (player.Position.Z < -mapWidth + 1)
                    player.Position += new Vector3(0, 0, 0.5f);
                ///right wall
                if (player.Position.Z > -1)
                    player.Position += new Vector3(0, 0, -0.5f);

                if (player.Invuln == false)
                    player.Health -= diff.playerWallDamage;

                soundBoundaryCollision.Play(effectsVolumeSlider.getValue() / 10, 0f, 0f);

                return CollisionType.Boundary;
            }

            //if collision with asteroid:
            for (int i = 0; i < targetList.Count; i++)
            {
                if (targetList[i].Bound.Contains(sphere) != ContainmentType.Disjoint)
                {
                    targetList.RemoveAt(i);
                    i--;

                    bullDistVec = (sphere.Center - player.Position);
                    PlayExplosion(bullDistVec.X);

                    if (player.Invuln == false)
                        player.Health -= diff.playerAsteroidDamage;

                    return CollisionType.Target;
                }
            }

            //if PowerUp
            for (int i = 0; i < powerUpList.Count; i++)
            {
                if (powerUpList[i].Bound.Contains(sphere) != ContainmentType.Disjoint)
                {
                    if (powerUpList[i].Type == PowerUpType.Health)
                    {
                        player.Health += 20;
                        if (player.Health > 100)
                            player.Health = 100;
                    }
                    if (powerUpList[i].Type == PowerUpType.Invuln)
                    {
                        player.Invuln = true;
                        player.InvulnStartTime = gameTime.TotalGameTime.TotalMilliseconds;
                    }
                    if (powerUpList[i].Type == PowerUpType.LavaCannon)
                    {
                        firingspeed = 1;
                        player.LavaCannon = true;
                        player.LavaCannonStartTime = gameTime.TotalGameTime.TotalMilliseconds;
                    }
                    powerUpList.RemoveAt(i);
                    i--;
                    soundPowerUp.Play(effectsVolumeSlider.getValue() / 10, 0f, 0f);
                }
            }
            return CollisionType.None;
        }

        public void PlayExplosion(float Distance)
        {
            if (Distance >= 90)
            {
                volume = 0.1f;
                soundExplosion.Play(volume * effectsVolumeSlider.getValue() / 10, 0, 0);
            }
            else
            {
                volume = (100 - Distance) / 100f;
                soundExplosion.Play(volume * effectsVolumeSlider.getValue() / 10, 0, 0);
            }
        }

        #endregion

        #region Draw Methods

        public override void Draw(GameTime gameTime)
        {
            // This game has a blue background. Why? Because!
            ScreenManager.GraphicsDevice.Clear(ClearOptions.Target, Color.CornflowerBlue, 0, 0);


            // If the game is transitioning on or off, fade it out to black.
            //if (TransitionPosition > 0 || pauseAlpha > 0)
            //{
            //    float alpha = MathHelper.Lerp(1f - TransitionAlpha, 1f, pauseAlpha / 2);

            //    ScreenManager.FadeBackBufferToBlack(alpha);
            //}

            device.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Transparent, 1.0f, 0);
            //If player is not in kinect camera range
            if (KINECT_ENABLE == true)
            {
                if (CheckOutOfBounds())
                {
                    Paused = true;
                    DrawPauseMenu(gameTime);
                    CheckforQuit();
                    if (Exit == true)
                        ReturnToMainMenu();
                    return;
                }
                else
                {
                    Paused = false;
                }
            }

            if (Paused == true)
            {
                if (gameOver == false)
                {
                    DrawPauseMenu(gameTime);
                    CheckforQuit();
                    if (Exit == true)
                        ReturnToMainMenu();

                }
                else
                {
                    CheckforEscape();
                    DrawGameOver();
                    if (Exit == true)
                    {
                        ReturnToMainMenu();
                    }
                }
                return;
            }
            DrawTunnel();
            DrawKinectDebug(true);
            player.Draw(projectionMatrix, viewMatrix);

            for (int i = 0; i < UFOList.Count; i++)
                UFOList[i].Draw(projectionMatrix, viewMatrix);

            //for (int i = 0; i < targetList.Count; i++)
            //    targetList[i].Draw(projectionMatrix, viewMatrix);

            DrawTargets();
            DrawStars();
            DrawPowerUps();
            DrawBullets();
            DrawHUD(gameTime);

            base.Draw(gameTime);
        }

        #region Drawing Objects

        private void DrawTunnel()
        {
            //Floor

            effect.CurrentTechnique = effect.Techniques["Textured"];
            effect.Parameters["xWorld"].SetValue(Matrix.Identity);
            effect.Parameters["xView"].SetValue(viewMatrix);
            effect.Parameters["xProjection"].SetValue(projectionMatrix);
            effect.Parameters["xTexture"].SetValue(sceneryTexture);

            foreach (EffectPass pass in effect.CurrentTechnique.Passes)
            {
                int i = 0;
                pass.Apply();
                device.SetVertexBuffer(mapVertexBuffer);
                device.SamplerStates[i] = SamplerState.LinearClamp;
                device.DrawPrimitives(PrimitiveType.TriangleList, 0, mapVertexBuffer.VertexCount / 3);
                i++;
            }
        }

        private void DrawBullets()
        {
            device.BlendState = BlendState.Additive;
            if (bulletList.Count > 0)
            {
                VertexPositionTexture[] bulletVertices = new VertexPositionTexture[bulletList.Count * 6];
                int i = 0;
                foreach (Bullet currentBullet in bulletList)
                {
                    Vector3 center = currentBullet.Position;

                    bulletVertices[i++] = new VertexPositionTexture(center, new Vector2(1, 1));
                    bulletVertices[i++] = new VertexPositionTexture(center, new Vector2(0, 0));
                    bulletVertices[i++] = new VertexPositionTexture(center, new Vector2(1, 0));

                    bulletVertices[i++] = new VertexPositionTexture(center, new Vector2(1, 1));
                    bulletVertices[i++] = new VertexPositionTexture(center, new Vector2(0, 1));
                    bulletVertices[i++] = new VertexPositionTexture(center, new Vector2(0, 0));
                }

                effect.CurrentTechnique = effect.Techniques["PointSprites"];
                effect.Parameters["xWorld"].SetValue(Matrix.Identity);
                effect.Parameters["xProjection"].SetValue(projectionMatrix);
                effect.Parameters["xView"].SetValue(viewMatrix);
                effect.Parameters["xCamPos"].SetValue(cameraPosition);
                effect.Parameters["xTexture"].SetValue(bulletTexture);
                effect.Parameters["xCamUp"].SetValue(cameraUpDirection);
                effect.Parameters["xPointSpriteSize"].SetValue(0.1f);

                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    device.DrawUserPrimitives(PrimitiveType.TriangleList, bulletVertices, 0, bulletList.Count * 2);
                }
            }

            if (bulletList2.Count > 0)
            {
                VertexPositionTexture[] bulletVertices2 = new VertexPositionTexture[bulletList2.Count * 6];
                int i = 0;
                foreach (Bullet currentBullet in bulletList2)
                {
                    Vector3 center = currentBullet.Position;

                    bulletVertices2[i++] = new VertexPositionTexture(center, new Vector2(1, 1));
                    bulletVertices2[i++] = new VertexPositionTexture(center, new Vector2(0, 0));
                    bulletVertices2[i++] = new VertexPositionTexture(center, new Vector2(1, 0));

                    bulletVertices2[i++] = new VertexPositionTexture(center, new Vector2(1, 1));
                    bulletVertices2[i++] = new VertexPositionTexture(center, new Vector2(0, 1));
                    bulletVertices2[i++] = new VertexPositionTexture(center, new Vector2(0, 0));
                }

                effect.CurrentTechnique = effect.Techniques["PointSprites"];
                effect.Parameters["xWorld"].SetValue(Matrix.Identity);
                effect.Parameters["xProjection"].SetValue(projectionMatrix);
                effect.Parameters["xView"].SetValue(viewMatrix);
                effect.Parameters["xCamPos"].SetValue(cameraPosition);
                effect.Parameters["xTexture"].SetValue(bulletTexture);
                effect.Parameters["xCamUp"].SetValue(cameraUpDirection);
                effect.Parameters["xPointSpriteSize"].SetValue(0.1f);

                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    device.DrawUserPrimitives(PrimitiveType.TriangleList, bulletVertices2, 0, bulletList2.Count * 2);
                }
            }


            device.BlendState = BlendState.Opaque;
        }

        private void DrawStars()
        {
            device.BlendState = BlendState.Additive;
            if (starList.Count > 0)
            {
                VertexPositionTexture[] starVertices = new VertexPositionTexture[starList.Count * 6];
                int i = 0;
                foreach (Star currentStar in starList)
                {
                    Vector3 center = currentStar.position;

                    starVertices[i++] = new VertexPositionTexture(center, new Vector2(1, 1));
                    starVertices[i++] = new VertexPositionTexture(center, new Vector2(0, 0));
                    starVertices[i++] = new VertexPositionTexture(center, new Vector2(1, 0));

                    starVertices[i++] = new VertexPositionTexture(center, new Vector2(1, 1));
                    starVertices[i++] = new VertexPositionTexture(center, new Vector2(0, 1));
                    starVertices[i++] = new VertexPositionTexture(center, new Vector2(0, 0));
                }

                effect.CurrentTechnique = effect.Techniques["PointSprites"];
                effect.Parameters["xWorld"].SetValue(Matrix.Identity);
                effect.Parameters["xProjection"].SetValue(projectionMatrix);
                effect.Parameters["xView"].SetValue(viewMatrix);
                effect.Parameters["xCamPos"].SetValue(cameraPosition);
                effect.Parameters["xTexture"].SetValue(starTexture);
                effect.Parameters["xCamUp"].SetValue(cameraUpDirection);
                effect.Parameters["xPointSpriteSize"].SetValue(0.1f);

                foreach (EffectPass pass in effect.CurrentTechnique.Passes)
                {
                    int m = 0;
                    pass.Apply();
                    device.SamplerStates[m] = SamplerState.LinearClamp;
                    device.DrawUserPrimitives(PrimitiveType.TriangleList, starVertices, 0, starList.Count * 2);
                    m++;
                }
            }
            device.BlendState = BlendState.Opaque;
        }

        private void DrawTargets()
        {
            for (int i = 0; i < targetList.Count; i++)
            {
                foreach (ModelMesh mesh in targetModel.Meshes)
                {
                    foreach (BasicEffect effect in mesh.Effects)
                    {
                        effect.EnableDefaultLighting();
                        effect.PreferPerPixelLighting = true;

                        //effect.World = Matrix.CreateTranslation(targetList[i].Bound.Center);
                        effect.World = Matrix.CreateScale(targetList[i].Radius) * Matrix.CreateTranslation(targetList[i].Bound.Center);
                        effect.Projection = projectionMatrix;
                        effect.View = viewMatrix;
                    }
                    mesh.Draw();
                }
            }
        }

        private void DrawPowerUps()
        {
            for (int i = 0; i < powerUpList.Count; i++)
            {
                //Matrix world = Matrix.CreateScale(.0135f, .0135f, .0135f) * Matrix.CreateTranslation(-.045f, 0, 0) * Matrix.CreateRotationY(MathHelper.Pi) * Matrix.CreateRotationZ(MathHelper.Pi) * Matrix.CreateFromQuaternion(powerUpList[i].Rotation) * Matrix.CreateTranslation(powerUpList[i].Position);

                foreach (ModelMesh mesh in powerUpList[i].Model.Meshes)
                {
                    foreach (BasicEffect effect in mesh.Effects)
                    {
                        effect.EnableDefaultLighting();
                        effect.PreferPerPixelLighting = true;

                        effect.World = Matrix.CreateTranslation(powerUpList[i].Bound.Center);
                        effect.World = Matrix.CreateScale(powerUpList[i].Radius) * Matrix.CreateTranslation(powerUpList[i].Bound.Center);
                        effect.Projection = projectionMatrix;
                        effect.View = viewMatrix;
                    }
                    mesh.Draw();
                }
            }   
        }

        #endregion

        #region Drawing HUD


        private void DrawHUD(GameTime gameTime)
        {
            //If you want this to appear when in debugmode, put it here 
            if (debugmode == true)
            {
                spriteBatch.Begin();
                spriteBatch.DrawString(smallFont, "Lava Cannon Demonstrate? " + lavaCannonDemonstrate.ToString(), new Vector2(20, 700), Color.White);

                spriteBatch.DrawString(smallFont, (player.Position + new Vector3(50, 0, 0)).X.ToString(), new Vector2(1200, 50), Color.White);
                spriteBatch.DrawString(smallFont, player.Position.Y.ToString(), new Vector2(1200, 75), Color.White);
                spriteBatch.DrawString(smallFont, player.Position.Z.ToString(), new Vector2(1200, 100), Color.White);

                if (UFOList.Count > 0)
                {
                    spriteBatch.DrawString(smallFont, UFOList[0].Position.X.ToString(), new Vector2(1200, 325), Color.Red);
                    spriteBatch.DrawString(smallFont, UFOList[0].Position.Y.ToString(), new Vector2(1200, 350), Color.Red);
                    spriteBatch.DrawString(smallFont, UFOList[0].Position.Z.ToString(), new Vector2(1200, 375), Color.Red);
                }
                spriteBatch.DrawString(smallFont, "UFOS: " +UFOList.Count.ToString(), new Vector2(20, 100), Color.CornflowerBlue);
                spriteBatch.DrawString(smallFont, "Asteroids: " + targetList.Count.ToString(), new Vector2(20, 125), Color.CornflowerBlue);
                spriteBatch.DrawString(smallFont, "Game Speed: " + gameSpeed.ToString(), new Vector2(20, 150), Color.CornflowerBlue);
                spriteBatch.DrawString(smallFont, "Current Time: " + gameTime.TotalGameTime.TotalMilliseconds.ToString(), new Vector2(20, 175), Color.CornflowerBlue);
                spriteBatch.DrawString(smallFont, "Bullets: " + bulletList.Count.ToString(), new Vector2(20, 200), Color.CornflowerBlue);

                //spriteBatch.DrawString(smallfont, "Highest Score " + GetHighScore(), new Vector2(1200, 470), Color.White);
                //To display vector coordinates of other objects (if needed for testing)
                
                spriteBatch.DrawString(smallFont, bullDistVec.X.ToString(), new Vector2(1200, 200), Color.White);

                spriteBatch.DrawString(smallFont, "Speed " + gameSpeed.ToString(), new Vector2(1200, 500), Color.White);
                spriteBatch.DrawString(smallFont, nextTunnel.ToString(), new Vector2(1200, 550), Color.White);

                //if (bulletList2.Count > 0)
                {
                    //spriteBatch.DrawString(smallfont, targetList[0].Bound.Center.X.ToString(), new Vector2(1200, 600), Color.Green);
                    //spriteBatch.DrawString(smallfont, targetList[0].Bound.Center.Y.ToString(), new Vector2(1200, 625), Color.Green);
                    //spriteBatch.DrawString(smallfont, targetList[0].Bound.Center.Z.ToString(), new Vector2(1200, 650), Color.Green);
                    spriteBatch.DrawString(smallFont, powerUpList.Count.ToString(), new Vector2(1200, 600), Color.Green);
                    spriteBatch.DrawString(smallFont, chance.ToString(), new Vector2(1200, 625), Color.Green);
                }
                //To display the viewmatrix in full to the screen
                /*
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M11).ToString(), new Vector2(1100, 200), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M12).ToString(), new Vector2(1150, 200), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M13).ToString(), new Vector2(1200, 200), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M14).ToString(), new Vector2(1250, 200), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M21).ToString(), new Vector2(1100, 225), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M22).ToString(), new Vector2(1150, 225), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M23).ToString(), new Vector2(1200, 225), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M24).ToString(), new Vector2(1250, 225), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M31).ToString(), new Vector2(1100, 250), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M32).ToString(), new Vector2(1150, 250), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M33).ToString(), new Vector2(1200, 250), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M34).ToString(), new Vector2(1250, 250), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M41).ToString(), new Vector2(1100, 275), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M42).ToString(), new Vector2(1150, 275), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M43).ToString(), new Vector2(1200, 275), Color.White);
                spriteBatch.DrawString(smallfont, ((int)viewMatrix.M44).ToString(), new Vector2(1250, 275), Color.White);
                */

                spriteBatch.End();
                device.DepthStencilState = DepthStencilState.Default;
            }

            ///If you want it to appear in general, put it here
            DrawReticle();

            //When game is running
            if (Paused == false)
            {
                //Draws the bar along the top
                spriteBatch.Begin();
                spriteBatch.Draw(hudRectangleBig, new Vector2(0, 0), Color.White);
                spriteBatch.Draw(hudRectangleSmall, new Vector2(5, 0), Color.White);

                //For the lives
                spriteBatch.DrawString(smallFont, "Lives", new Vector2(windowWidth - 150, 2), Color.White);
                for (int i = 0; i < player.Lives; i++)
                {
                    spriteBatch.Draw(bar_life, new Vector2(windowWidth - ((i + 2) * 20), 0), Color.White);
                }

                //Health Bar Start
                spriteBatch.Draw(bar_health_end, new Vector2(windowWidth - 401, 0), Color.White);
                spriteBatch.DrawString(smallFont, "Health", new Vector2(windowWidth - 480, 2), Color.White);
                //Health Bar Main
                for (int i = 0; i < player.Health; i++)
                {
                    spriteBatch.Draw(bar_health_enabled, new Vector2(windowWidth - (400 - 2 * i), 0), Color.White);
                    spriteBatch.Draw(bar_health_enabled, new Vector2(windowWidth - (400 - 2 * i - 1), 0), Color.White);
                }
                for (int i = 0; i < 100 - player.Health; i++)
                {
                    spriteBatch.Draw(bar_health_disabled, new Vector2(windowWidth - 200 - 2 * i, 0), Color.White);
                    spriteBatch.Draw(bar_health_disabled, new Vector2(windowWidth - 200 - 2 * i - 1, 0), Color.White);
                }
                //Health Bar End
                spriteBatch.Draw(bar_health_end, new Vector2(windowWidth - 200, 0), Color.White);
                Color draw = new Color();
                if (player.Health < 50) { draw = Color.White; } else { draw = Color.Black; }
                spriteBatch.DrawString(smallFont, player.Health.ToString() + "%", new Vector2(windowWidth - 315 - ((player.Health.ToString().ToCharArray().Count() - 3) * 10), 2), draw);

                //Lava Cannon
                if (player.LavaCannon != true)
                {
                    spriteBatch.Draw(powerUpHUDList[0].disabled, new Vector2(windowWidth - 550, 0), Color.White);
                }
                else
                {
                    spriteBatch.Draw(powerUpHUDList[0].enabled, new Vector2(windowWidth - 550, 0), Color.White);
                    //Draw the number of seconds remaining
                    spriteBatch.DrawString(smallFont, ((10000 - (gameTime.TotalGameTime.TotalMilliseconds - player.LavaCannonStartTime)) / 1000).ToString("0"), new Vector2(windowWidth - 530, 2), Color.White);
                }

                //Invincibility
                if (player.Invuln != true)
                {
                    spriteBatch.Draw(powerUpHUDList[1].disabled, new Vector2(windowWidth - 550 - 60, 0), Color.White);
                }
                else
                {
                    spriteBatch.Draw(powerUpHUDList[1].enabled, new Vector2(windowWidth - 550 - 60, 0), Color.White);
                    //Draw the number of seconds remaining
                    spriteBatch.DrawString(smallFont, ((5000 - (gameTime.TotalGameTime.TotalMilliseconds - player.InvulnStartTime)) / 1000).ToString("0"), new Vector2(windowWidth - 530 - 60, 2), Color.White);
                }

                //Invert Y
                if (invertY)
                {
                    spriteBatch.Draw(powerUpHUDList[2].enabled, new Vector2(windowWidth - 550 - 60 - 60, 0), Color.White);
                }
                else
                {
                    spriteBatch.Draw(powerUpHUDList[2].disabled, new Vector2(windowWidth - 550 - 60 - 60, 0), Color.White);
                }

                //Music Muted/not muted
                if (MediaPlayer.IsMuted)
                {
                    spriteBatch.Draw(bar_music_muted, new Vector2(160, 0), Color.White);
                }
                else
                {
                    spriteBatch.Draw(bar_music_unmuted, new Vector2(160, 0), Color.White);
                }

                //Score
                spriteBatch.DrawString(smallFont, "Score: " + player.TotalScore.ToString(), new Vector2(200, 2), Color.Red);

                //SPACE KINECT!!!!!!!!!!!!!!!!!!!!!!!!!!
                spriteBatch.DrawString(smallFont, "Space Kinect", new Vector2(20, 2), Color.White);
                spriteBatch.DrawString(gameFont, "Ammo: " + ammocount.ToString(), new Vector2(20, 40), Color.White);
                spriteBatch.End();
                device.DepthStencilState = DepthStencilState.Default;


            }
        }

        private void DrawReticle()
        {
            //Draws a reticle in the center of the screen (values obtained using trial and error lol)
            spriteBatch.Begin();
            //spriteBatch.Draw(reticle, new Vector2(graphics.PreferredBackBufferWidth / 2 - 15, graphics.PreferredBackBufferHeight / 2 - 157), Color.White);
            spriteBatch.Draw(reticle, new Vector2(ScreenManager.SpriteBatch.GraphicsDevice.Viewport.Width / 2 - 15, ScreenManager.SpriteBatch.GraphicsDevice.Viewport.Height / 2 - 157), Color.White);
            spriteBatch.End();
            //Required to make things draw in correct order
            device.DepthStencilState = DepthStencilState.Default;
        }

        private void PowerUpCues(GameTime gameTime)
        {
            //If firing speed powerup is enabled draw remaining time
            if (player.LavaCannon == true)
            {
                spriteBatch.Begin();
                spriteBatch.DrawString(smallFont, "Powerup time remaining: " + ((10000 - (gameTime.TotalGameTime.TotalMilliseconds - player.LavaCannonStartTime)) / 1000).ToString("0"), new Vector2(50, 100), Color.White);
                spriteBatch.End();
                device.DepthStencilState = DepthStencilState.Default;
            }

            if (player.Invuln == true)
            {
                spriteBatch.Begin();
                spriteBatch.DrawString(smallFont, "Invulnarability left: " + ((5000 - (gameTime.TotalGameTime.TotalMilliseconds - player.InvulnStartTime)) / 1000).ToString("0"), new Vector2(50, 125), Color.White);
                spriteBatch.End();
                device.DepthStencilState = DepthStencilState.Default;
            }
        }

        private void DrawGameElements()
        {
            spriteBatch.Begin();
            spriteBatch.DrawString(smallFont, "Score: " + player.TotalScore, new Vector2(50, 25), Color.White);
            spriteBatch.DrawString(smallFont, "Lives: " + player.Lives, new Vector2(50, 50), Color.White);
            spriteBatch.DrawString(smallFont, "Health: " + player.Health, new Vector2(50, 75), Color.White);
            spriteBatch.End();
            device.DepthStencilState = DepthStencilState.Default;

        }

        private void DrawGameOver()
        {
            spriteBatch.Begin();
            float offSet2;

            float offSet1 = (float)((GlobalVars.windowWidth - 324) / 2);
            if (player.TotalScore >= 1000)
                offSet2 = (float)((GlobalVars.windowWidth - 264) / 2);
            else if (player.TotalScore >= 100)
                offSet2 = (float)((GlobalVars.windowWidth - 244) / 2);
            else
                offSet2 = (float)((GlobalVars.windowWidth - 224) / 2);

            float offSet3 = (float)((GlobalVars.windowWidth - 624) / 2);
            spriteBatch.DrawString(debugFont, "GAME OVER", new Vector2(offSet1, 200), Color.Red);
            spriteBatch.DrawString(menuFont, "Your Score: " + player.TotalScore.ToString(), new Vector2(offSet2, 300), Color.White);
            spriteBatch.DrawString(menuFont, "Press Escape to return to the main menu", new Vector2(offSet3, 500), Color.White);
            spriteBatch.End();
            device.DepthStencilState = DepthStencilState.Default;
            
        }

        #endregion

        #endregion

        #region Pause Menu

        private void DrawPauseMenu(GameTime gameTime)
        {   
            spriteBatch.Begin();
            //Draw Background
            spriteBatch.Draw(pauseScreen, new Vector2(offsetX,0), Color.White);
            //Draw head z position
            if (Head.Z == 0)
                spriteBatch.DrawString(debugFont, Head.Z.ToString(), new Vector2((float)(GlobalVars.windowWidth / 2), (float)(GlobalVars.windowHeight - 75)), Color.Black);
            else
                spriteBatch.DrawString(debugFont, Head.Z.ToString(), new Vector2((float)(GlobalVars.windowWidth / 2 - 100), (float)(GlobalVars.windowHeight - 75)), Color.Black);
            //Draw invert y true/false
            spriteBatch.DrawString(debugFont, invertY.ToString(), new Vector2((float)(ScreenManager.SpriteBatch.GraphicsDevice.Viewport.Width * .47), (float)(GlobalVars.windowHeight - 555)), Color.Black);

            #region Sliders
            //If music volume is being adjusted
            if (musicVolumeSelected == true)
            {
                //Update sliderball position
                updateSlider(musicVolumeSlider);
                //Draw sliderballs
                spriteBatch.Draw(selectedSliderBall, new Vector2(musicVolumeSlider.getSlider().X - 14, musicVolumeSlider.getSlider().Y - 14), Color.White);
                spriteBatch.Draw(musicSliderBall, new Vector2(effectsVolumeSlider.getSlider().X - 14, effectsVolumeSlider.getSlider().Y - 14), Color.White);
                MediaPlayer.Volume = musicVolumeSlider.getValue() / 10;
            }
            //If effects volume is being adjusted
            else if (effectsVolumeSelected == true)
            {
                updateSlider(effectsVolumeSlider);
                spriteBatch.Draw(selectedSliderBall, new Vector2(effectsVolumeSlider.getSlider().X - 14, effectsVolumeSlider.getSlider().Y - 14), Color.White);
                spriteBatch.Draw(musicSliderBall, new Vector2(musicVolumeSlider.getSlider().X - 14, musicVolumeSlider.getSlider().Y - 14), Color.White);
            }

            //If no volume is being adjusted
            else
            {
                //Draw purple balls
                spriteBatch.Draw(musicSliderBall, new Vector2(musicVolumeSlider.getSlider().X - 14, musicVolumeSlider.getSlider().Y - 14), Color.White);
                spriteBatch.Draw(musicSliderBall, new Vector2(effectsVolumeSlider.getSlider().X - 14, effectsVolumeSlider.getSlider().Y - 14), Color.White);
            }
            #endregion

            //Draw volume values
            string musicValue = (musicVolumeSlider.getValue() * 10).ToString("N0");
            string effectsValue = (effectsVolumeSlider.getValue() * 10).ToString("N0");
            if (musicValue == "-1")
                musicValue = "0";
            if (effectsValue == "-1")
                effectsValue = "0";

            spriteBatch.DrawString(debugFont, musicValue, new Vector2(995+offsetX, 292), Color.Black);
            spriteBatch.DrawString(debugFont, effectsValue, new Vector2(995+offsetX, 360), Color.Black);
            spriteBatch.End();
            base.Draw(gameTime);
            ProcessKeyboard(gameTime);
            return;

        }

        private void updateSlider(SliderBar slider)
        {
            //RHHOME is the value where the right hand was when slider had started adjusting


            //If within the range to drag slider
            if (RH.X < (RHHome.X + 100) && RH.X > RHHome.X - 1)
            {
                float difference = RH.X - RHHome.X;
                if (difference == -1)
                    difference = 0;

                if (musicVolumeSelected)
                {
                    musicVolumeSlider.setValue(difference / 10);
                }
                else if (effectsVolumeSelected)
                {
                    effectsVolumeSlider.setValue(difference / 10);
                }
            }

        }
        #endregion

        #region Kinect/Sound Methods

        private bool CheckOutOfBounds()
        {
            //Returns false if player's head is out of bounds
            if ((Head.Z == 0 || Head.Z < 1.8 || Head.Z > 2.3) && KINECT_ENABLE == true || musicVolumeSelected == true || effectsVolumeSelected == true)
            {
                return true;
            }
            return false;
        }

        private void DrawKinectDebug(bool handdata)
        {
            if (debug == true)
            {

                spriteBatch.Begin();

                if (debugcamera == true)
                {
                    //Draws kinect camera stream
                    spriteBatch.Draw(kinectRGB, new Vector2(0, 0), null, Color.White, 0, Vector2.Zero, .60f, SpriteEffects.None, 0);

                }
                if (handdata == true)
                {
                    //Draws current positions of limbs
                    spriteBatch.DrawString(debugFont, "LeftHand X: " + LH.X, new Vector2(0, graphics.PreferredBackBufferHeight - 100), Color.Red);
                    spriteBatch.DrawString(debugFont, "LeftHand Y: " + LH.Y, new Vector2(0, graphics.PreferredBackBufferHeight - 70), Color.Red);
                    spriteBatch.DrawString(debugFont, "LeftHand HOMEXY: " + LHHome.X + " " + LHHome.Y, new Vector2(0, graphics.PreferredBackBufferHeight - 40), Color.Red);

                    spriteBatch.DrawString(debugFont, "RightHand X: " + RH.X, new Vector2(0, graphics.PreferredBackBufferHeight - 200), Color.Red);
                    spriteBatch.DrawString(debugFont, "RightHand Y: " + RH.Y, new Vector2(0, graphics.PreferredBackBufferHeight - 170), Color.Red);
                    spriteBatch.DrawString(debugFont, "RightHand Z: " + RH.Z, new Vector2(0, graphics.PreferredBackBufferHeight - 140), Color.Red);
                    spriteBatch.DrawString(debugFont, "RightHand HOMEXY: " + RHHome.X + " " + RHHome.Y, new Vector2(0, graphics.PreferredBackBufferHeight - 40), Color.Red);
                }

                spriteBatch.End();
                device.DepthStencilState = DepthStencilState.Default;
            }
        }

        private void DiscoverKinectSensor()
        {
            foreach (KinectSensor s in KinectSensor.KinectSensors)
            {
                if (s.Status == KinectStatus.Connected)
                {
                    sensor = s;
                    InitializeKinect();
                    return;
                }

            }
        }

        private void InitializeKinect()
        {
            sensor.ColorStream.Enable(ColorImageFormat.YuvResolution640x480Fps15);
            sensor.ColorFrameReady += new EventHandler<ColorImageFrameReadyEventArgs>(sensor_ColorFrameReady);

            sensor.SkeletonStream.Enable(new TransformSmoothParameters()
            {
                Smoothing = 0.5f,
                Correction = 0.5f,
                Prediction = 0.5f,
                JitterRadius = 0.1f,
                MaxDeviationRadius = 0.04f
            });
            sensor.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(sensor_SkeletonFrameReady);
            try
            {
                sensor.Start();
            }
            catch
            {
                sensor.Stop();
            }

        }

        private void InitializeSpeech()
        {
            //requires kinect connected else ri == null
            RecognizerInfo ri = SpeechRecognitionEngine.InstalledRecognizers().Where(r => r.Id == "SR_MS_en-US_Kinect_10.0").FirstOrDefault();
            if (ri == null)
            {
                throw new ApplicationException("Could not locate speech recognizer. Ensure you have the Kinect Speech SDK/runtime/MSKinectLangPack_enUS installed.");
            }

            //Phrases that will be recognised added
            Choices phrases = new Choices();
            phrases.Add(
                "faster",
                "slower",
                "stop",
                "invert y",
                "music volume",
                "effects volume",
                "okay");
            GrammarBuilder gb = new GrammarBuilder();
            //adding our phrases to the grammar builder
            gb.Append(phrases);
            //gb.Culture = ri.Culture;

            sr = new SpeechRecognitionEngine(ri.Id);

            if (KINECT_ENABLE)
            {
                audio = sensor.AudioSource; //using kinect as source not pc mic
                audio.AutomaticGainControlEnabled = false; // Per sample documentation, "Important to turn this off for speech recognition"
                audio.EchoCancellationMode = EchoCancellationMode.None; //as above
                stream = audio.Start();
                sr.SetInputToAudioStream(stream, new SpeechAudioFormatInfo(EncodingFormat.Pcm, 16000, 16, 1, 32000, 2, null));
            }
            else
            {
                sr.SetInputToDefaultAudioDevice();
            }

            sr.LoadGrammar(new Grammar(gb));

            sr.SpeechRecognized += new EventHandler<SpeechRecognizedEventArgs>(sr_SpeechRecognized);
            sr.SpeechHypothesized += new EventHandler<SpeechHypothesizedEventArgs>(sr_SpeechHypothesized);
            sr.SpeechRecognitionRejected += new EventHandler<SpeechRecognitionRejectedEventArgs>(sr_SpeechRecognitionRejected);
            //set the recognition engine to keep running after recognizing a command.
            //if we had used RecognizeMode.Single, the engine would quite listening after
            //the first recognized command.
            sr.RecognizeAsync(RecognizeMode.Multiple);
        }

        void sr_SpeechRecognitionRejected(object sender, SpeechRecognitionRejectedEventArgs e)
        {

        }

        void sr_SpeechHypothesized(object sender, SpeechHypothesizedEventArgs e)
        {

        }

        void sr_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            if (e.Result.Text.ToLower() == "faster" && e.Result.Confidence >= 0.7)
            {
                gameSpeed *= 2;
            }
            else if (e.Result.Text.ToLower() == "slower" && e.Result.Confidence >= 0.7)
            {
                gameSpeed /= 2;
            }
            else if (e.Result.Text.ToLower() == "stop" && e.Result.Confidence >= 0.7)
            {
                this.ScreenManager.RemoveScreen(this);
                //Exit();
            }
            else if (e.Result.Text.ToLower() == "invert y" && e.Result.Confidence >= 0.7)
            {
                if (Paused == true)
                {
                    if (invertY == true)
                    {
                        invertY = false;
                    }
                    else
                    {
                        invertY = true;
                    }
                }
            }
            else if (e.Result.Text.ToLower() == "music volume" && e.Result.Confidence >= 0.55 && Paused == true)
            {
                musicVolumeSelected = true;
                RHHome = RH;
                LHHome = LH;
            }
            else if (e.Result.Text.ToLower() == "effects volume" && e.Result.Confidence >= 0.55 && Paused == true)
            {
                effectsVolumeSelected = true;
                RHHome = RH;
                LHHome = LH;
            }
            else if (e.Result.Text.ToLower() == "okay" && e.Result.Confidence >= 0.7)
            {
                musicVolumeSelected = false;
                effectsVolumeSelected = false;

            }


            //if some speech has been recognized, test if its speech we want
            //switch (e.Result.Text.ToLower())
            //{
            //    case "faster":
            //        gameSpeed *= 2;
            //        break;
            //    case "slower":
            //        gameSpeed /= 2;
            //        break;
            //    case "stop":
            //        Exit();
            //        break;

            //    case "invert y":
            //        if (Paused == true)
            //        {
            //            if (invertY == true)
            //            {
            //                invertY = false;
            //            }
            //            else
            //            {
            //                invertY = true;
            //            }
            //        }
            //        break;
            //}


        }
        //LAGGY
        private void sensor_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
        {
            ColorImageFrame imageFrame = e.OpenColorImageFrame();

            if (imageFrame != null && debugcamera == true)
            {
                byte[] pixelsFromFrame = new byte[imageFrame.PixelDataLength];
                imageFrame.CopyPixelDataTo(pixelsFromFrame);
                Color[] colors = new Color[imageFrame.Height * imageFrame.Width];
                kinectRGB = new Texture2D(graphics.GraphicsDevice, imageFrame.Width, imageFrame.Height);

                int index = 0;
                for (int y = 0; y < imageFrame.Height; y++)
                {
                    for (int x = 0; x < imageFrame.Width; x++, index += 4)
                    {
                        colors[y * imageFrame.Width + x] = new Color(pixelsFromFrame[index + 2], pixelsFromFrame[index + 1], pixelsFromFrame[index]);
                    }
                }
                kinectRGB.SetData(colors);

            }
        }

        private void sensor_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            using (SkeletonFrame frame = e.OpenSkeletonFrame())
            {
                if (frame != null)
                {
                    Skeleton[] skeletonData = new Skeleton[frame.SkeletonArrayLength];
                    frame.CopySkeletonDataTo(skeletonData);
                    Skeleton playerSkeleton = (from s in skeletonData where s.TrackingState == SkeletonTrackingState.Tracked select s).FirstOrDefault();
                    if (playerSkeleton != null)
                    {

                        Joint rightHand = playerSkeleton.Joints[JointType.HandRight].ScaleTo(640, 480, 1, 1);
                        Joint leftHand = playerSkeleton.Joints[JointType.HandLeft].ScaleTo(640, 480, 1, 1);
                        Joint head = playerSkeleton.Joints[JointType.Head].ScaleTo(640, 480, 1, 1);
                        RH = new Vector3(rightHand.Position.X, rightHand.Position.Y, rightHand.Position.Z);
                        LH = new Vector3(leftHand.Position.X, leftHand.Position.Y, leftHand.Position.Z);
                        Head = new Vector3(head.Position.X, head.Position.Y, head.Position.Z);



                    }
                }
            }
        }

        #endregion

        #region Score Recording
        /// <summary>
        /// This method to record a score in a txt file and 
        /// </summary>
        /// <param name="x"></param>
        private void RecordScore(int x)
        {
            writer = File.AppendText(path);
            writer.WriteLine(player.TargetScore.ToString());
            writer.Close();

        }
        /// <summary>
        /// Getting the highest score
        /// </summary>
        /// <returns>high score</returns>
        private int GetHighScore()
        {
            string path = @"Score.txt";
            reader = File.OpenText(path);
            int highScore = 0;
            while (reader.Peek() != -1)
            {
                int score = int.Parse(reader.ReadLine());
                if (score > highScore)
                {
                    highScore = score;
                }
            }
            reader.Close();
            return highScore;
        }

        #endregion


        //  a handy little function that gives a random float between two
        // values. This will be used in several places in the sample, in particilar in
        // ParticleSystem.InitializeParticle.
        internal static float RandomBetween(float min, float max)
        {
            return min + (float)rnd.NextDouble() * (max - min);
        }


    }




}


